import type { FileRouteTypes } from "@/routeTree.gen";
import { useAuthStore } from "@/store";
import { isAuthorized, isFunction, isString } from "@/utils";
import { Button, Popconfirm, Tooltip } from "@arco-design/web-react";
import { useNavigate } from "@tanstack/react-router";
import type { ReactNode } from "react";
import { useModal } from "../Modal";
import { useStContext } from "./context";
import type { StColumnButtonOptions, StRenderFunction } from "./types";

type StColumnButtonProps<TModel> = {
	record: TModel;
	options: StColumnButtonOptions<TModel>;
};

export function isButtonVisible<TModel>(
	record: TModel,
	options: StColumnButtonOptions<TModel>,
): boolean {
	const { iif, iifBehavior, acl } = options;
	if (iif && !iif(record) && iifBehavior !== "disabled") return false;
	if (acl && !isAuthorized(acl)) return false;

	return true;
}

export default function StColumnButton<TModel>({
	record,
	options,
}: StColumnButtonProps<TModel>): ReactNode {
	const {
		text,
		icon,
		type,
		click,
		pop,
		iif,
		iifBehavior,
		tooltip,
		acl,
		modal,
	} = options;

	// 禁用或隐藏
	let disabled = false;
	if (iif) {
		if (!iif(record)) {
			if (iifBehavior === "disabled") disabled = true;
			else return null;
		}
	}

	// Authorization
	const { isAuthorized } = useAuthStore();
	if (acl && !isAuthorized(acl)) return null;

	const { reloadData, loadData } = useStContext();
	const navigate = useNavigate();

	const { create: createModal } = useModal();

	// 按钮点击事件
	let callback:
		| StRenderFunction<TModel, void>
		| StRenderFunction<TModel, FileRouteTypes["to"]>;
	let handleClick: () => void = () => undefined;
	if (click) {
		if (click === "reload") {
			callback = reloadData;
		} else if (click === "load") {
			callback = () => loadData(1);
		} else {
			callback = click;
		}

		let typeValue = type;
		if (!type && !pop) typeValue = "none";
		if (typeValue === "none") {
			if (isFunction(click)) {
				handleClick = () => callback(record);
			}
		} else if (typeValue === "link") {
			const link = (callback as StRenderFunction<TModel, FileRouteTypes["to"]>)(
				record,
			);
			handleClick = () => navigate({ to: link });
		} else if (typeValue === "modal" && modal) {
			const { component, params, modalConfig, title, width } = modal;
			const modalTitle = title
				? isString(title)
					? title
					: title(record)
				: undefined;
			const modalParams = params
				? isFunction(params)
					? params(record)
					: params
				: undefined;
			handleClick = () => {
				createModal(component, modalParams as object, {
					...modalConfig,
					title: modalTitle,
					width,
				}).then((res) => {
					if (res) {
						callback(record);
					}
				});
			};
		}
	}

	const buttonText = text ? (isString(text) ? text : text(record)) : null;
	const buttonIcon = icon?.(record);
	let StButton = (
		<Button
			color="primary"
			type="text"
			icon={buttonIcon}
			disabled={disabled}
			onClick={handleClick}
			className="px-0"
		>
			{buttonText}
		</Button>
	);

	// 提示
	if (tooltip) {
		StButton = <Tooltip content={tooltip}>{StButton}</Tooltip>;
	}

	// 气泡确认框
	let showPop = pop;
	if (type === "del" && pop === undefined) {
		showPop = true;
	}
	if (showPop) {
		let popTitle = "确定删除吗？";
		if (isString(pop)) popTitle = pop;
		StButton = (
			<Popconfirm content={popTitle} onOk={() => (callback as (m: TModel) => void)(record)}>
				{StButton}
			</Popconfirm>
		);
	}

	return StButton;
}
